package edu.wust.cs.cm;

import java.util.ArrayList;
import java.util.Iterator;

import android.app.Activity;
import android.content.ContentProviderOperation;
import android.content.Context;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

//添加名片界面
public final class ContactAdder extends Activity
{
    public static final String TAG = "ContactsAdder";
    public static final String ACCOUNT_NAME = "";
    public static final String ACCOUNT_TYPE = "";

    //界面包含的UI控件
    private EditText mContactEmailEditText;
    private ArrayList<Integer> mContactEmailTypes;
    private Spinner mContactEmailTypeSpinner; //类似下拉列表选择器
    private EditText mContactNameEditText;
    private EditText mContactPhoneEditText;
    private ArrayList<Integer> mContactPhoneTypes;
    private Spinner mContactPhoneTypeSpinner;
    private Button mContactSaveButton;
    private Button mContactCancelButton;
    private ArrayList<Integer> mContactImTypes;
    private EditText mContactImEditText;
    private Spinner mContactImTypeSpinner;

    /**
     * Called when the activity is first created. Responsible for initializing the UI.
     */
    //界面最先调用的入口函数
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        Log.v(TAG, "Activity State: onCreate()");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.contact_adder);

        // Obtain handles to UI objects
        mContactNameEditText = (EditText) findViewById(R.id.contactNameEditText);
        mContactPhoneEditText = (EditText) findViewById(R.id.contactPhoneEditText);
        mContactEmailEditText = (EditText) findViewById(R.id.contactEmailEditText);
        mContactPhoneTypeSpinner = (Spinner) findViewById(R.id.contactPhoneTypeSpinner);
        mContactEmailTypeSpinner = (Spinner) findViewById(R.id.contactEmailTypeSpinner);
        mContactSaveButton = (Button) findViewById(R.id.contactSaveButton);
        mContactCancelButton = (Button) findViewById(R.id.contactCancelButton);
        mContactImEditText = (EditText) findViewById(R.id.contactImEditText);
        mContactImTypeSpinner = (Spinner) findViewById(R.id.contactImTypeSpinner);

        // Prepare list of supported account types
        // Note: Other types are available in ContactsContract.CommonDataKinds
        //       Also, be aware that type IDs differ between Phone and Email, and MUST be computed
        //       separately.
        mContactPhoneTypes = new ArrayList<Integer>();
        mContactPhoneTypes.add(ContactsContract.CommonDataKinds.Phone.TYPE_HOME);
        mContactPhoneTypes.add(ContactsContract.CommonDataKinds.Phone.TYPE_WORK);
        mContactPhoneTypes.add(ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE);
        mContactPhoneTypes.add(ContactsContract.CommonDataKinds.Phone.TYPE_OTHER);
        mContactEmailTypes = new ArrayList<Integer>();
        mContactEmailTypes.add(ContactsContract.CommonDataKinds.Email.TYPE_HOME);
        mContactEmailTypes.add(ContactsContract.CommonDataKinds.Email.TYPE_WORK);
        mContactEmailTypes.add(ContactsContract.CommonDataKinds.Email.TYPE_MOBILE);
        mContactEmailTypes.add(ContactsContract.CommonDataKinds.Email.TYPE_OTHER);
        mContactImTypes = new ArrayList<Integer>();
        mContactImTypes.add(ContactsContract.CommonDataKinds.Im.PROTOCOL_QQ);
        mContactImTypes.add(ContactsContract.CommonDataKinds.Im.PROTOCOL_MSN);
        mContactImTypes.add(ContactsContract.CommonDataKinds.Im.PROTOCOL_GOOGLE_TALK);
        mContactImTypes.add(ContactsContract.CommonDataKinds.Im.PROTOCOL_ICQ);
        mContactImTypes.add(ContactsContract.CommonDataKinds.Im.PROTOCOL_YAHOO);
        
        // Populate list of account types for phone
        ArrayAdapter<String> adapter;
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        Iterator<Integer> iter;
        iter = mContactPhoneTypes.iterator();
        while (iter.hasNext()) {
            adapter.add(ContactsContract.CommonDataKinds.Phone.getTypeLabel(
                    this.getResources(),
                    iter.next(),
                    getString(R.string.undefinedTypeLabel)).toString());
        }
        mContactPhoneTypeSpinner.setAdapter(adapter);
        mContactPhoneTypeSpinner.setPrompt(getString(R.string.selectLabel));

        // Populate list of account types for email
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        iter = mContactEmailTypes.iterator();
        while (iter.hasNext()) {
            adapter.add(ContactsContract.CommonDataKinds.Email.getTypeLabel(
                    this.getResources(),
                    iter.next(),
                    getString(R.string.undefinedTypeLabel)).toString());
        }
        mContactEmailTypeSpinner.setAdapter(adapter);
        mContactEmailTypeSpinner.setPrompt(getString(R.string.selectLabel));

        // Populate list of account types for IM
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        iter = mContactImTypes.iterator();
        while (iter.hasNext()) {
            adapter.add(ContactsContract.CommonDataKinds.Im.getProtocolLabel(
                    this.getResources(),
                    iter.next(),
                    getString(R.string.undefinedTypeLabel)).toString());
        }
        mContactImTypeSpinner.setAdapter(adapter);
        mContactImTypeSpinner.setPrompt(getString(R.string.selectLabel));
        
        //为保存按钮添加Click事件响应器
        mContactSaveButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                onSaveButtonClicked();
            }
        });
       //为取消按钮添加Click事件响应器
        mContactCancelButton.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				finish();
			}
		});
    }

    /**
     * Actions for when the Save button is clicked. Creates a contact entry and terminates the
     * activity.
     */
    //单击 保存按钮时要做的函数
    private void onSaveButtonClicked() {
        Log.v(TAG, "Save button clicked");
        createContactEntry();
        finish();
    }

    /**
     * Creates a contact entry from the current UI values in the account named by mSelectedAccount.
     */
    //创建一个Contact实例
    protected void createContactEntry() {
        // Get values from UI
    	//从控件中得到Contact的各个属性的值
        String name = mContactNameEditText.getText().toString();
        String phone = mContactPhoneEditText.getText().toString();
        String email = mContactEmailEditText.getText().toString();
        String im = mContactImEditText.getText().toString();
        int phoneType = mContactPhoneTypes.get(
                mContactPhoneTypeSpinner.getSelectedItemPosition());
        int emailType = mContactEmailTypes.get(
                mContactEmailTypeSpinner.getSelectedItemPosition());
        int imType = mContactImTypes.get(mContactImTypeSpinner.getSelectedItemPosition());

        // Prepare contact creation request
        //
        // Note: We use RawContacts because this data must be associated with a particular account.
        //       The system will aggregate this with any other data for this contact and create a
        //       corresponding entry in the ContactsContract.Contacts provider for us.
        //编译一组ContentProviderOperation将Contact数据注入其中
        ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
        ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, ACCOUNT_TYPE)
                .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, ACCOUNT_NAME)
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name)
                .withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, name)
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
                .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType)
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
                .withValue(ContactsContract.Data.MIMETYPE,
                        ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Email.DATA, email)
                .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType)
                .build());
        ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
        		.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
        		.withValue(ContactsContract.Data.MIMETYPE, 
        				ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
        		.withValue(ContactsContract.CommonDataKinds.Im.DATA, im)
        		.withValue(ContactsContract.CommonDataKinds.Im.PROTOCOL, imType)
        		.build());

        // Ask the Contact provider to create a new contact
        Log.i(TAG,"Selected account: " +  ACCOUNT_TYPE + " (" + ACCOUNT_NAME + ")");
        Log.i(TAG,"Creating contact: " + name);
        try {
        	//执行这些ContentProviderOperation将Contact数据存入数据库
            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (Exception e) {
            // Display warning
            Context ctx = getApplicationContext();
            CharSequence txt = getString(R.string.contactCreationFailure);
            int duration = Toast.LENGTH_SHORT;
            Toast toast = Toast.makeText(ctx, txt, duration);
            toast.show();

            // Log exception
            Log.e(TAG, "Exceptoin encoutered while inserting contact: " + e);
        }
    }

    /**
     * Called when this activity is about to be destroyed by the system.
     */
    @Override
    public void onDestroy() {
        // Remove AccountManager callback
        super.onDestroy();
    }
}
